try:
    import wx
    from wx import glcanvas
except ImportError:
    raise ImportError, "Required dependency wx.glcanvas not present"

try:
    from OpenGL.GL import *
except ImportError:
    raise ImportError, "Required dependency OpenGL not present"

import time
import pynwheel
import galaxy_vis
import main

class GLFrame(wx.Frame, pynwheel.pynwheel):
    """wx version of pynwheel, thank you wxPython."""

    def __init__(self, parent, id, title, galaxyvis, pos=wx.DefaultPosition,
                 size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE,
                 name='frame'):
        self.toolkit = "wx"
        self.galaxyvis = galaxyvis

        #
        # Forcing a specific style on the window.
        #   Should this include styles passed?
        style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE

        super(GLFrame, self).__init__(parent, id, title, pos, size, style, name)

        self.GLinitialized = False
        attribList = (glcanvas.WX_GL_RGBA, # RGBA
                      glcanvas.WX_GL_DOUBLEBUFFER, # Double Buffered
                      glcanvas.WX_GL_DEPTH_SIZE, 24) # 24 bit


        self.split_vertical = wx.SplitterWindow(self, wx.ID_ANY)
        self.left_panel = wx.Panel(self.split_vertical, wx.ID_ANY)
        self.right_panel = wx.Panel(self.split_vertical, wx.ID_ANY)
        self.split_vertical.SplitVertically(self.left_panel, self.right_panel)

        self.expander = wx.BoxSizer(wx.VERTICAL)

        self.split_horizontal = wx.SplitterWindow(self.left_panel, wx.ID_ANY)
        self.top_panel = wx.Panel(self.split_horizontal, wx.ID_ANY)
        self.bottom_panel = wx.Panel(self.split_horizontal, wx.ID_ANY)
        self.split_horizontal.SplitHorizontally(self.top_panel, self.bottom_panel)

        self.expander.Add(self.split_horizontal, -1, wx.EXPAND)
        self.left_panel.SetSizer(self.expander)

        self.gl_sizer = wx.BoxSizer(wx.VERTICAL)

        #
        # Create the canvas
        self.canvas = glcanvas.GLCanvas(self.top_panel, size = (200, 200), attribList=attribList)
        self.gl_sizer.Add(self.canvas, -1, wx.EXPAND)
        self.top_panel.SetSizer(self.gl_sizer)
        
        #
        # Set the event handlers.
        self.canvas.Bind(wx.EVT_ERASE_BACKGROUND, self.processEraseBackgroundEvent)
        self.canvas.Bind(wx.EVT_SIZE, self.processSizeEvent)
        self.canvas.Bind(wx.EVT_PAINT, self.processPaintEvent)
        self.canvas.Bind(wx.EVT_MOTION, self.motionEvent)
        self.Bind(wx.EVT_IDLE, self._normal_draw)

        self.sizer_vertical = wx.BoxSizer(wx.VERTICAL)

        self.code = wx.TextCtrl(self.bottom_panel, style=wx.TE_MULTILINE)
   
        self.execute = wx.Button(self.bottom_panel, -1, "Execute")
        self.execute.Bind(wx.EVT_BUTTON, self.eval_it)
        self.sizer_vertical.Add(self.code, -1, wx.EXPAND)
        self.sizer_vertical.Add(self.execute, 0, wx.EXPAND)

        self.bottom_panel.SetSizer(self.sizer_vertical)

        self.control = wx.TextCtrl(self.right_panel, style=wx.TE_MULTILINE)
        self.control.SetEditable(False)
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.sizer.Add(self.control, 1, wx.EXPAND)
        self.right_panel.SetSizer(self.sizer)

#        self.SetSizer(self.sizer)
#        self.SetAutoLayout(1)
#        self.sizer.Fit(self)
        self.Show()

    #
    # Canvas Proxy Methods

    def GetGLExtents(self):
        """Get the extents of the OpenGL canvas."""
        return self.canvas.GetClientSize()

    def SwapBuffers(self):
        """Swap the OpenGL buffers."""
        self.canvas.SwapBuffers()

    #
    # wxPython Window Handlers
    def _normal_draw(self, event):
        self.OnDraw()
        event.RequestMore()

    def motionEvent(self, event):
        if event.m_leftDown:
            self.galaxyvis.motionFunc(event.m_x, event.m_y)

    def processEraseBackgroundEvent(self, event):
        """Process the erase background event."""
        pass # Do nothing, to avoid flashing on MSWin

    def processSizeEvent(self, event):
        """Process the resize event."""
        if self.canvas.GetContext():
            # Make sure the frame is shown before calling SetCurrent.
            self.Show()
            self.canvas.SetCurrent()

            size = self.GetGLExtents()
            self.OnReshape(size.width, size.height)
            self.canvas.Refresh(False)
        event.Skip()

    def processPaintEvent(self, event):
        """Process the drawing event."""
        self.canvas.SetCurrent()

        # This is a 'perfect' time to initialize OpenGL ... only if we need to
        if not self.GLinitialized:
            self.OnInitGL()
            self.GLinitialized = True

        self.OnDraw()
        event.Skip()

    #
    # GLFrame OpenGL Event Handlers

    def OnInitGL(self):
        """Initialize OpenGL for use in the window."""
        self.galaxyvis.initGL()

    def OnReshape(self, width, height):
        """Reshape the OpenGL viewport based on the dimensions of the window."""
        self.galaxyvis.resizeGLScene(width, height)

    def OnDraw(self, *args, **kwargs):
        time.sleep(0.01)
        "Draw the window."
        self.galaxyvis.drawGLScene()
        self.SwapBuffers()
        self.check_data()

def start(data, perf):
    app = wx.PySimpleApp()
    gv = galaxy_vis.galaxyvis(400, 400, data, perf)
    
    frame = GLFrame(None, -1, 'pynwheel', gv, size=(800, 600))
    frame.Show()
    
    app.MainLoop()
    app.Destroy()
